const async = require('async')

// 模拟异步任务的函数
const asyncTask = (taskName, duration, shouldFail = false) => {
  return new Promise((resolve, reject) => {
    console.log(`任务 ${taskName} 开始`)
    setTimeout(() => {
      if (shouldFail) {
        console.log(`任务 ${taskName} 失败`)
        reject(new Error(`任务 ${taskName} 失败`))
      } else {
        console.log(`任务 ${taskName} 完成`)
        resolve(`任务 ${taskName} 成功`)
      }
    }, duration)
  })
}

// 定义任务队列
const queue = async.queue(async (task, callback) => {
  try {
    const result = await asyncTask(task.name, task.duration, task.shouldFail)
    callback(null, result)
  } catch (error) {
    callback(error, task)
  }
}, 1) // 并发数设置为1

// 监听队列完成事件
queue.drain(() => {
  console.log('所有任务已完成')
})

// 处理任务完成和失败的回调
const handleTaskResult = (err, result, task) => {
  if (err) {
    console.error(`任务 ${task.name} 出错:`, err.message)
    if (task.retries > 0) {
      console.log(`任务 ${task.name} 还有 ${task.retries} 次重试机会，正在重新添加到队列...`)
      // 重新添加任务到队列，并减少重试次数
      addTask({...task, retries: task.retries - 1})
    } else {
      console.error(`任务 ${task.name} 已达到最大重试次数，放弃执行。`)
    }
  } else {
    console.log(result)
  }
}

// 辅助函数：添加任务到队列
const addTask = (task) => {
  queue.push(task, (err, result) => handleTaskResult(err, result, task))
}

// 定义任务对象
const tasks = [
  {name: 'A', duration: 1000, retries: 3},
  {name: 'B', duration: 500, shouldFail: true, retries: 2},
  // {name: 'C', duration: 300, retries: 1},
  // {name: 'D', duration: 400, shouldFail: true, retries: 2}
]

// 添加所有任务到队列
tasks.forEach(addTask)
